package com.timeshare.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.timeshare.dto.LoginRequest;
import com.timeshare.dto.RegisterRequest;
import com.timeshare.dto.UserVO;
import com.timeshare.entity.User;
import com.timeshare.mapper.UserMapper;
import com.timeshare.service.UserService;
import com.timeshare.utils.JwtUtil;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 用户服务实现
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
    private final PasswordEncoder passwordEncoder;
    private final JwtUtil jwtUtil;
    
    public UserServiceImpl(PasswordEncoder passwordEncoder, JwtUtil jwtUtil) {
        this.passwordEncoder = passwordEncoder;
        this.jwtUtil = jwtUtil;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(RegisterRequest request) {
        // 检查用户名是否已存在
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, request.getUsername());
        if (this.count(wrapper) > 0) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 检查邮箱是否已存在
        if (request.getEmail() != null && !request.getEmail().isEmpty()) {
            wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getEmail, request.getEmail());
            if (this.count(wrapper) > 0) {
                throw new RuntimeException("邮箱已被使用");
            }
        }
        
        // 创建用户
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setNickname(request.getNickname());
        user.setEmail(request.getEmail());
        user.setPhone(request.getPhone());
        user.setSchool(request.getSchool());
        user.setMajor(request.getMajor());
        user.setGrade(request.getGrade());
        user.setPoints(100); // 初始积分
        user.setCreditScore(100); // 初始信誉分
        user.setStatus(0); // 正常状态
        user.setRole(0); // 普通用户
        
        this.save(user);
    }
    
    @Override
    public String login(LoginRequest request) {
        // 查询用户
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, request.getUsername());
        User user = this.getOne(wrapper);
        
        if (user == null) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        // 验证密码
        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        // 检查账号状态
        if (user.getStatus() == 1) {
            throw new RuntimeException("账号已被封禁");
        }
        
        // 生成Token
        return jwtUtil.generateToken(user.getId(), user.getUsername());
    }
    
    @Override
    public UserVO getCurrentUser(Long userId) {
        User user = this.getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user, userVO);
        return userVO;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(Long userId, User user) {
        User existUser = this.getById(userId);
        if (existUser == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 只允许更新特定字段
        if (user.getNickname() != null) {
            existUser.setNickname(user.getNickname());
        }
        if (user.getAvatar() != null) {
            existUser.setAvatar(user.getAvatar());
        }
        if (user.getEmail() != null) {
            existUser.setEmail(user.getEmail());
        }
        if (user.getPhone() != null) {
            existUser.setPhone(user.getPhone());
        }
        if (user.getSchool() != null) {
            existUser.setSchool(user.getSchool());
        }
        if (user.getMajor() != null) {
            existUser.setMajor(user.getMajor());
        }
        if (user.getGrade() != null) {
            existUser.setGrade(user.getGrade());
        }
        if (user.getBio() != null) {
            existUser.setBio(user.getBio());
        }
        if (user.getSkillTags() != null) {
            existUser.setSkillTags(user.getSkillTags());
        }
        
        this.updateById(existUser);
    }
    
    @Override
    public UserVO getUserById(Long userId) {
        User user = this.getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user, userVO);
        return userVO;
    }
    
    @Override
    public com.baomidou.mybatisplus.extension.plugins.pagination.Page<User> getUserList(Integer page, Integer size, String keyword) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<User> userPage = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page, size);
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        
        if (keyword != null && !keyword.isEmpty()) {
            wrapper.and(w -> w.like(User::getUsername, keyword)
                    .or().like(User::getNickname, keyword)
                    .or().like(User::getEmail, keyword));
        }
        
        wrapper.orderByDesc(User::getCreateTime);
        return this.page(userPage, wrapper);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void banUser(Long userId) {
        User user = this.getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        user.setStatus(1); // 封禁
        this.updateById(user);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void unbanUser(Long userId) {
        User user = this.getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        user.setStatus(0); // 正常
        this.updateById(user);
    }
}

